package com.tamtamy.jtta.parser;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.methods.GetMethod;

import com.tamtamy.jtta.JTTAClient;
import com.tamtamy.jtta.conf.JTTAProperties;
import com.tamtamy.jtta.data.Comment;
import com.tamtamy.jtta.data.CommentList;
import com.tamtamy.jtta.data.ContentFile;
import com.tamtamy.jtta.data.ContentLink;
import com.tamtamy.jtta.data.ContentList;
import com.tamtamy.jtta.data.ContentMessage;
import com.tamtamy.jtta.data.ContentWidget;
import com.tamtamy.jtta.data.GroupDetails;
import com.tamtamy.jtta.data.GroupList;
import com.tamtamy.jtta.data.Metadata;
import com.tamtamy.jtta.data.NetworkDetails;
import com.tamtamy.jtta.data.NetworkList;
import com.tamtamy.jtta.data.Notice;
import com.tamtamy.jtta.data.NoticeList;
import com.tamtamy.jtta.data.OnLineUsersList;
import com.tamtamy.jtta.data.TagDetail;
import com.tamtamy.jtta.data.TagList;
import com.tamtamy.jtta.data.Token;
import com.tamtamy.jtta.data.UserDetail;
import com.tamtamy.jtta.data.UserStatsGenerationDetails;
import com.tamtamy.jtta.data.UserStatsGenerationList;
import com.tamtamy.jtta.data.UserStatsList;
import com.tamtamy.jtta.data.UserTag;
import com.tamtamy.jtta.data.UsersList;
import com.tamtamy.jtta.data.json.JSONComment;
import com.tamtamy.jtta.data.json.JSONCommentList;
import com.tamtamy.jtta.data.json.JSONContentFile;
import com.tamtamy.jtta.data.json.JSONContentLink;
import com.tamtamy.jtta.data.json.JSONContentList;
import com.tamtamy.jtta.data.json.JSONContentMessage;
import com.tamtamy.jtta.data.json.JSONContentWidget;
import com.tamtamy.jtta.data.json.JSONGroupDetails;
import com.tamtamy.jtta.data.json.JSONGroupList;
import com.tamtamy.jtta.data.json.JSONMetadata;
import com.tamtamy.jtta.data.json.JSONNetworkDetails;
import com.tamtamy.jtta.data.json.JSONNetworkList;
import com.tamtamy.jtta.data.json.JSONNotice;
import com.tamtamy.jtta.data.json.JSONNoticeList;
import com.tamtamy.jtta.data.json.JSONOnLineUsersList;
import com.tamtamy.jtta.data.json.JSONTagDetail;
import com.tamtamy.jtta.data.json.JSONTagList;
import com.tamtamy.jtta.data.json.JSONToken;
import com.tamtamy.jtta.data.json.JSONUserDetail;
import com.tamtamy.jtta.data.json.JSONUserStatsGenerationDetails;
import com.tamtamy.jtta.data.json.JSONUserStatsGenerationList;
import com.tamtamy.jtta.data.json.JSONUserStatsList;
import com.tamtamy.jtta.data.json.JSONUserTag;
import com.tamtamy.jtta.data.json.JSONUsersList;
import com.tamtamy.jtta.exception.NoResultException;
import com.tamtamy.jtta.exception.ParsingException;
import com.tamtamy.jtta.exception.UnauthorizedException;
import com.tamtamy.jtta.utility.APIUtility;

/**
 * @author a.pellegatta
 *
 */
public class JSONParser implements Parser {

	private APIUtility apiUtility;
	
	public JSONParser(JTTAClient jttaClient, String url, boolean debug) {
		this.apiUtility = new APIUtility(jttaClient, url, JTTAProperties.REQUEST_JSON, debug);
	}

	@Override
	public Object getData(String url) throws UnauthorizedException {
		GetMethod httpRequest = new GetMethod(url);
		JSONObject jsonObject = new JSONObject();
		String response = apiUtility.getResponse(httpRequest,url);		
		try {
			jsonObject = JSONObject.fromObject(response);  
		} catch (Exception exception) {
			System.out.println(exception.getLocalizedMessage());
			throw new UnauthorizedException("Error parsing " + url + " : " + exception.getLocalizedMessage());
		}
		return jsonObject;
	}
	
	@Override
	public Token doLogin(String username, String password) throws UnauthorizedException {
		String loginURL = apiUtility.getLoginURL(username, password);
		JSONObject loginJSON = (JSONObject)getData(loginURL); 
		Token token  = new JSONToken(loginJSON);
		apiUtility.setToken(token);
		return token;
	}
	
	@Override
	public boolean isValidToken(String username, String token) {
		try {
			apiUtility.setToken(new Token(token));
			String userDetailURL = apiUtility.getUserDetailURL(username);
			getData(userDetailURL);
			return true;
		} catch (UnauthorizedException unauthorizedException) {
			return false;
		}
	}

	@Override
	public void doLogout() throws UnauthorizedException {
		String logoutURL = apiUtility.getLogoutURL();
		getData(logoutURL);
	}

	@Override
	public void downloadContent(String contentID) throws UnauthorizedException {
		String downloadContentURL = apiUtility.getDownloadContentURL(contentID);
		getData(downloadContentURL);
	}

	@Override
	public Comment getComment(long commentID) throws UnauthorizedException {
		Comment comment = new Comment();
		String commentURL = apiUtility.getCommentURL(commentID);
		JSONObject commentJSON = (JSONObject) getData(commentURL);
		comment = new JSONComment(commentJSON);
		return comment;	
	}

	@Override
	public CommentList getCommentList(long startOffset, long limit)	throws UnauthorizedException, ParsingException {
		CommentList commentList = new CommentList();
		String commentListURL = apiUtility.getCommentListURL(startOffset, limit);
		try {
			JSONObject commentListJSON = (JSONObject) getData(commentListURL);
			commentList = new JSONCommentList(commentListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}
		return commentList;	
	}

	@Override
	public ContentFile getContentFile(String contentID)	throws UnauthorizedException {
		ContentFile contentFile = new ContentFile();
		String contentFileURL = apiUtility.getContentFileURL(contentID);
		JSONObject contentFileJSON =  (JSONObject) getData(contentFileURL);
		contentFile = new JSONContentFile(contentFileJSON);
		return contentFile;	
	}

	@Override
	public ContentLink getContentLink(String contentID)	throws UnauthorizedException {
		ContentLink contentLink = new ContentLink();
		String contentLinkURL = apiUtility.getContentLinkURL(contentID);
		JSONObject contentLinkJSON =  (JSONObject) getData(contentLinkURL);
		contentLink = new JSONContentLink(contentLinkJSON);
		return contentLink;	
	}

	@Override
	public ContentList getContentList(long startOffset, long limit, String filter, String order) throws UnauthorizedException,ParsingException {
		ContentList contentList = new ContentList();
		String contentURL = apiUtility.getContentListURL(startOffset, limit, filter, order);
		try{
			JSONObject contentListJSON = (JSONObject) getData(contentURL);
			contentList = new JSONContentList(contentListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}
		return contentList;	
	}

	@Override
	public ContentMessage getContentMessage(String contentID) throws UnauthorizedException {
		ContentMessage contentMessage = new ContentMessage();
		String contentMessageURL = apiUtility.getContentMessageURL(contentID);
		JSONObject contentMessageJSON =  (JSONObject) getData(contentMessageURL);
		contentMessage = new JSONContentMessage(contentMessageJSON);
		return contentMessage;
	}

	@Override
	public ContentWidget getContentWidget(String contentID)	throws UnauthorizedException {
		ContentWidget  contentWidget = new ContentWidget();
		String contentWidgetURL = apiUtility.getContentWidgetURL(contentID);
		JSONObject contentWidgetJSON =  (JSONObject) getData(contentWidgetURL);
		contentWidget = new JSONContentWidget(contentWidgetJSON);
		return  contentWidget;	
	}
	
	@Override
	public GroupDetails getGroupDetails(String groupID)	throws UnauthorizedException {
		GroupDetails groupDetails = new GroupDetails();
		String groupDetailsURL = apiUtility.getGroupDetailsURL(groupID);				
		JSONObject groupDetailsJSON = (JSONObject) getData(groupDetailsURL);
		groupDetails = new JSONGroupDetails(groupDetailsJSON);
		return groupDetails;	
	}

	@Override
	public GroupList getGroupList(long startOffset, long limit)	throws UnauthorizedException, ParsingException {
		GroupList groupList = new GroupList();
		String groupListURL = apiUtility.getGroupListURL(startOffset, limit);		
		try {
			JSONObject groupListJSON = (JSONObject) getData(groupListURL);
			groupList = new JSONGroupList(groupListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return groupList;	
	}

	@Override
	public Metadata getMetadata(String url) throws UnauthorizedException, ParsingException {
		Metadata metadata = new Metadata();
		try {
			String metadataURL = apiUtility.getMetadataURL(url);
			JSONObject metadataJSON = (JSONObject) getData(metadataURL);
			metadata = new JSONMetadata(metadataJSON);
		} catch (Exception exception) {
			throw new ParsingException(exception.getMessage());
		}
		return metadata;
	}

	@Override
	public NetworkDetails getNetworkDetails(String networkID) throws UnauthorizedException {
		NetworkDetails networkDetails = new NetworkDetails();
		String networkDetailsURL = apiUtility.getNetworkDetailsURL(networkID);				
		JSONObject networkDetailsJSON = (JSONObject) getData(networkDetailsURL);
		networkDetails = new JSONNetworkDetails(networkDetailsJSON);
		return networkDetails;	
	}

	@Override
	public NetworkList getNetworkList(long startOffset, long limit) throws UnauthorizedException, ParsingException {
		NetworkList networkList = new NetworkList();
		String networkListURL = apiUtility.getNetworkListURL(startOffset, limit);
		try {
			JSONObject networkListJSON = (JSONObject) getData(networkListURL);
			networkList = new JSONNetworkList(networkListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return networkList;	
	}

	
	@Override
	public NetworkList getNetworkList(long startOffset, long limit, String filter) throws UnauthorizedException, ParsingException {
		NetworkList networkList = new NetworkList();
		String networkListURL = apiUtility.getNetworkListURL(startOffset, limit, filter);
		try {
			JSONObject networkListJSON = (JSONObject) getData(networkListURL);
			networkList = new JSONNetworkList(networkListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return networkList;	
	}
	
	@Override
	public NetworkList getNetworkListWithChatEnabled(long startOffset, long limit) throws UnauthorizedException, ParsingException {
		NetworkList networkListWithChatEnabled = new NetworkList();
		String networkListWithChatEnableURL = apiUtility.getNetworkListWithChatEnabledURL(startOffset, limit);
		try {
			JSONObject networkListWithChatEnabledJSON = (JSONObject) getData(networkListWithChatEnableURL);
			networkListWithChatEnabled = new JSONNetworkList(networkListWithChatEnabledJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return networkListWithChatEnabled;	
	}

	
	@Override
	public NetworkList getNetworkListWithChatEnabled(long startOffset, long limit, String filter) throws UnauthorizedException, ParsingException {
		NetworkList networkListWithChatEnabled = new NetworkList();
		String networkListWithChatEnableURL = apiUtility.getNetworkListWithChatEnabledURL(startOffset, limit, filter);
		try {
			JSONObject networkListWithChatEnabledJSON = (JSONObject) getData(networkListWithChatEnableURL);
			networkListWithChatEnabled = new JSONNetworkList(networkListWithChatEnabledJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return networkListWithChatEnabled;	
	}
	
	@Override
	public Notice getNotice(long noticeID) throws UnauthorizedException {
		Notice notice = new Notice();
		String noticeURL = apiUtility.getNoticeURL(noticeID);	
		JSONObject noticeJSON = (JSONObject) getData(noticeURL);
		notice = new JSONNotice(noticeJSON);
		return notice;	
	}

	@Override
	public NoticeList getNoticeList(long startOffset, long limit, String filter) throws UnauthorizedException, ParsingException {
		NoticeList noticeList = new NoticeList();
		String noticeListURL = apiUtility.getNoticeListURL(startOffset, limit, filter);	
		try {
			JSONObject noticeListJSON = (JSONObject) getData(noticeListURL);
			noticeList = new JSONNoticeList(noticeListJSON);
		}catch (NoResultException noResultException) {
			// TODO some actions?	
		}
		return noticeList;	
	}

	@Override
	public OnLineUsersList getOnLineUsersList(long startOffset, long limit)	throws UnauthorizedException {
		OnLineUsersList onLineUsersList = new OnLineUsersList();
		String onlineUsersListURL = apiUtility.getOnlineUsersList(startOffset, limit);
		JSONObject onLineUsersListJSON =  (JSONObject) getData(onlineUsersListURL);				
		onLineUsersList = new JSONOnLineUsersList(onLineUsersListJSON);
		return onLineUsersList;
	}


	@Override
	public TagDetail getTagDetail(String tag) throws UnauthorizedException {
		TagDetail tagDetail = new TagDetail();
		String tagListDetailURL = apiUtility.getTagListDetailURL(tag);
		JSONObject tagDetailJSON =  (JSONObject) getData(tagListDetailURL);
		tagDetail = new JSONTagDetail(tagDetailJSON);
		return tagDetail;
	}


	@Override
	public TagList getTagList(long startOffset, long limit)	throws UnauthorizedException {
		TagList tagList = new TagList();
		String tagListURL = apiUtility.getTagListURL(startOffset, limit);
		JSONObject tagListJSON =  (JSONObject) getData(tagListURL);
		tagList = new JSONTagList(tagListJSON);
		return tagList;		
	}


	@Override
	public UserDetail getUserDetail(String userID) throws UnauthorizedException {
		UserDetail userDetail = new UserDetail();
		String userDetailURL = apiUtility.getUserDetailURL(userID);
		JSONObject userDetailJSON = (JSONObject) getData(userDetailURL);
		userDetail = new JSONUserDetail(userDetailJSON);
		return userDetail;	
	}

	@Override
	public UserStatsGenerationDetails getUserStatsGenerationDetails(String userStatsID, long startOffset, long limit) throws UnauthorizedException {
		UserStatsGenerationDetails userStatsGenerationDetails = new UserStatsGenerationDetails();
		String userStatsGenerationDetailsURL = apiUtility.getUserStatsGenerationDetailsURL(userStatsID, startOffset, limit);		
		JSONObject userStatsGenerationDetailsJSON = (JSONObject) getData(userStatsGenerationDetailsURL);
		userStatsGenerationDetails = new JSONUserStatsGenerationDetails(userStatsGenerationDetailsJSON);
		return userStatsGenerationDetails;	
	}

	@Override
	public UserStatsGenerationList getUserStatsGenerationList(long startOffset,	long limit) throws UnauthorizedException, ParsingException {
		UserStatsGenerationList userStatsGenerationList = new UserStatsGenerationList();
		String userStatsGenerationListURL = apiUtility.getUserStatsGenerationListURL(startOffset, limit);
		try {
			JSONObject userStatsGenerationListJSON = (JSONObject) getData(userStatsGenerationListURL);
			userStatsGenerationList = new JSONUserStatsGenerationList(userStatsGenerationListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}
		return userStatsGenerationList;	
	}

	@Override
	public UserStatsList getUserStatsList(String userID, long startOffset, long limit) throws UnauthorizedException {
		UserStatsList userStats = new UserStatsList();
		String userStatsURL = apiUtility.getUserStatsURL(userID, startOffset, limit);
		try {
			JSONObject userStatsJSON = (JSONObject) getData(userStatsURL);
			userStats = new JSONUserStatsList(userStatsJSON);	
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}
		return userStats;	
	}

	@Override
	public UserTag getUserTag(String filter) throws UnauthorizedException {
		UserTag userTag = new UserTag();
		String userTagURL = apiUtility.getUserTagURL(filter);
		JSONObject userTagJSON = (JSONObject) getData(userTagURL);
		userTag = new JSONUserTag(userTagJSON);
		return userTag;	
	}

	@Override
	public UserTag getUserTag(String userID, String filter)	throws UnauthorizedException {
		UserTag userTag = new UserTag();
		String userTagURL = apiUtility.getUserTagURL(userID, filter);
		JSONObject userTagJSON = (JSONObject) getData(userTagURL);
		userTag = new JSONUserTag(userTagJSON);
		return userTag;	
	}

	@Override
	public UsersList getUsersList(long startOffset, long limit, String filter) throws UnauthorizedException, ParsingException {
		UsersList userList = new UsersList();
		String userListURL = apiUtility.getUserListURL(startOffset, limit, filter);
		try {
			JSONObject userListJSON = (JSONObject) getData(userListURL);
			userList = new JSONUsersList(userListJSON);
		} catch (NoResultException noResultException) {
			// TODO some actions?	
		}	
		return userList;
	}

}
